package esb.chapter10.auditor;

import javax.jbi.JBIException;
import javax.jbi.messaging.MessageExchange;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.servicemix.jbi.audit.AbstractAuditor;
import org.apache.servicemix.jbi.audit.AuditorException;
import org.apache.servicemix.jbi.event.ExchangeEvent;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.Database;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.XMLResource;

/**
 * Exist auditor which stored received messages in the database
 * 
 * @author nl24167
 */
public class ExistAuditor extends AbstractAuditor {

    private static Log LOG = LogFactory.getLog(ExistAuditor.class);

    private String databaseName;
    private String url;
    private Collection collection;

    // implemented methods

    /**
     * This method will be called whenever the NMR receiver a message.
     */
    public void exchangeSent(ExchangeEvent event) {
        XMLResource document;
        try {
            document = (XMLResource) collection.createResource(null,
                    "XMLResource");
            Source source = event.getExchange().getMessage("in").getContent();
            Transformer tr = TransformerFactory.newInstance().newTransformer();
            DOMResult result = new DOMResult();
            tr.transform(source, result);
            document.setContentAsDOM(result.getNode());
            collection.storeResource(document);
            event.getExchange().getMessage("in").setContent(
                    new DOMSource(result.getNode()));
        } catch (Exception e) {
            LOG.warn("Error persisting message in database", e);
        }
    }

    public String getDescription() {
        return "Simple persister to eXist";
    }

    // lifecycle methods

    /**
     * Setup the connection to the collection
     */
    @Override
    protected void doStart() throws JBIException {
        super.doStart();
        try {
            collection = getCollection();
        } catch (Exception e) {
            throw new JBIException("Error setting up auditor: "
                    + e.getMessage(), e);
        }
    }

    /**
     * Close the collection
     */
    @Override
    protected void doStop() throws JBIException {
        super.doStop();
        try {
            collection.close();
        } catch (XMLDBException e) {
            throw new JBIException("Error closing auditing connection: "
                    + e.getMessage(), e);
        }

    }

    // unimplemented methods

    @Override
    public int deleteExchangesByIds(String[] arg0) throws AuditorException {
        return 0;
    }

    @Override
    public int getExchangeCount() throws AuditorException {
        return 0;
    }

    @Override
    public String[] getExchangeIdsByRange(int arg0, int arg1)
            throws AuditorException {
        return null;
    }

    @Override
    public MessageExchange[] getExchangesByIds(String[] arg0)
            throws AuditorException {
        return null;
    }

    // private helpers

    private Collection getCollection() throws Exception {
        String driver = "org.exist.xmldb.DatabaseImpl";
        Class cl = Class.forName(driver);
        Database database = (Database) cl.newInstance();
        DatabaseManager.registerDatabase(database);

        return DatabaseManager.getCollection(url + databaseName);
    }

    // getters and setters

    public String getDatabase() {
        return databaseName;
    }

    public void setDatabase(String database) {
        this.databaseName = database;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

}
